package com.x.dao;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Component;

import com.x.model.Location;
import com.x.model.Project;

@Component
public class ProjectDAO extends BaseDAO {
	
	private LocationDAO locationDAO;

	public void saveProject(Project project) {
		this.getSession().merge(project);
	}

	public void update(Project project) {
		this.getSession().saveOrUpdate(project);
	}

	public String count() {
		Query query = this.getSession().createSQLQuery(
				"select  count(*) from Project");
		return query.uniqueResult().toString();
	}

	public String findNum(String sql) {
		Query query = this.getSession().createSQLQuery(sql);
		return query.uniqueResult().toString();
	}

	public Map<String, Object> list(int startIndex, int length,
			List<String[]> wherePart, List<String[]> odrerPart) {

		Criteria c = this.getSession().createCriteria(Project.class);
		c.setProjection(Projections.rowCount());
		Object total = c.uniqueResult();
		for (String[] order : odrerPart) {
			if (order[0].equals("name") || order[0].equals("description")
					|| order[0].equals("type")) {
				if (order[1].equals("desc")) {
					c.addOrder(Order.desc(order[0]));
				} else {
					c.addOrder(Order.asc(order[0]));
				}
			}
		}
		for (String[] where : wherePart) {
			if (where[0].equals("name") || where[0].equals("description")
					|| where[0].equals("type")) {
				c = c.add(Restrictions.like(where[0], where[1],
						MatchMode.ANYWHERE));
			}
		}
		c = c.createCriteria("location");
		for (String[] order : odrerPart) {
			if (order[0].equals("district")) {
				if (order[1].equals("desc")) {
					c.addOrder(Order.desc("name"));
				} else {
					c.addOrder(Order.asc("name"));
				}
			}
		}
		for (String[] where : wherePart) {
			if (where[0].equals("district")) {
				c = c.add(Restrictions.like("name", where[1],
						MatchMode.ANYWHERE));
			}
		}
		c = c.createCriteria("parent");
		for (String[] order : odrerPart) {
			if (order[0].equals("city")) {
				if (order[1].equals("desc")) {
					c.addOrder(Order.desc("name"));
				} else {
					c.addOrder(Order.asc("name"));
				}
			}
		}
		for (String[] where : wherePart) {
			if (where[0].equals("city")) {
				c = c.add(Restrictions.like("name", where[1],
						MatchMode.ANYWHERE));
			}
		}
		c = c.createCriteria("parent");
		for (String[] order : odrerPart) {
			if (order[0].equals("province")) {
				if (order[1].equals("desc")) {
					c.addOrder(Order.desc("name"));
				} else {
					c.addOrder(Order.asc("name"));
				}
			}
		}
		for (String[] where : wherePart) {
			if (where[0].equals("province")) {
				c = c.add(Restrictions.like("name", where[1],
						MatchMode.ANYWHERE));
			}
		}

		Object recordsFiltered = c.uniqueResult();
		c.setProjection(null);
		c.setFirstResult(startIndex);
		c.setMaxResults(length);
		List<Project> projects = c.list();

		List<Map<String, String>> datas = new ArrayList<>();

		for (Project project : projects) {
			String id = project.getId();
			String name = project.getName();
			String district = project.getLocation().getName();
			String city = project.getLocation().getParent().getName();
			String province = project.getLocation().getParent().getParent()
					.getName();
			String type = project.getType();
			String description = project.getDescription();

			Map<String, String> data = new HashMap<>();
			data.put("id", id);
			data.put("name", name);
			data.put("district", district);
			data.put("city", city);
			data.put("province", province);
			data.put("type", type);
			data.put("description", description);
			datas.add(data);
		}
		Map<String, Object> result = new HashMap<String, Object>();
		result.put("recordsTotal", total);
		result.put("recordsFiltered", recordsFiltered);
		result.put("data", datas);
		return result;
	}

	public boolean notExist(String name, String type, String district) {
		Criteria c = this.getSession().createCriteria(Project.class);
		c = c.add(Restrictions.eq("name", name));
		c = c.add(Restrictions.eq("type", type));
		c = c.createCriteria("location");
		c = c.add(Restrictions.eq("id", district));
		return c.list().isEmpty();
	}

	public void create(String name, String type, String description, Location location) {
		Project project = new Project();
		project.setName(name);
		project.setType(type);
		project.setDescription(description);
		project.setLocation(location);
		this.getSession().merge(project);
		
	}

	public Project getProjectById(String id){
		Criteria c = this.getSession().createCriteria(Project.class);
		c = c.add(Restrictions.eq("id", id));
		return (Project) c.uniqueResult();
	}
	
	public void delete(String id) {
		Project project = getProjectById(id);
		this.getSession().delete(project);
	}

}
